#include "myapp.h"
#include "de_dialog.h"

DECLARE_APP(MyApp);

BEGIN_EVENT_TABLE(DetailEditor, wxDialog)
	EVT_BUTTON(detaile_ok,DetailEditor::de_OkBtn_clicked)
	EVT_BUTTON(detaile_can,DetailEditor::de_CanBtn_clicked)
	EVT_BUTTON(detaile_num0,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num1,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num2,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num3,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num4,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num5,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num6,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num7,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num8,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num9,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num9,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_num00,DetailEditor::de_CalcNumBtn_clicked)
	EVT_BUTTON(detaile_add,DetailEditor::de_CalcFuncBtn_clicked)
	EVT_BUTTON(detaile_sub,DetailEditor::de_CalcFuncBtn_clicked)
	EVT_BUTTON(detaile_multi,DetailEditor::de_CalcFuncBtn_clicked)
	EVT_BUTTON(detaile_div,DetailEditor::de_CalcFuncBtn_clicked)
	EVT_BUTTON(detaile_enter,DetailEditor::de_CalcEnterBtn_clicked)
	EVT_BUTTON(detaile_clear,DetailEditor::de_CalcClearBtn_clicked)
	EVT_BUTTON(detaile_cleartax,DetailEditor::de_CalcClearTax_clicked)
	//EVT_COMMAND_SCROLL(detaile_tax,DetailEditor::de_CalcTax_scrolled)
	EVT_RADIOBOX(detaile_iobox,DetailEditor::de_IncomeType_selected)
	EVT_COMBOBOX(detaile_expenselist,DetailEditor::de_ExpenseList_selected)
	EVT_RADIOBOX(detaile_input,DetailEditor::de_InputType_changed)
	EVT_BUTTON(detaile_includetax,DetailEditor::de_CalcIncludeTax_clicked)
	EVT_NOTEBOOK_PAGE_CHANGED(detaile_setlist,DetailEditor::de_SettingList_changed)
END_EVENT_TABLE() 


DetailEditor::DetailEditor(wxWindow *parent)
:wxDialog(parent, wxID_ANY, _("Input a transaction"), wxDefaultPosition, wxDefaultSize)
{
	SetClientSize(wxSize(540,480));
	
	wxString inputtype_items[] = {
		_("Normal transaction"),
		_("Balance alignment")
	};
	wxString incometype_items[] = {
		_("income"),_("expenditure")
	};
	wxStaticBox *sb = new wxStaticBox(this,wxID_ANY,_("Date"));
	wxStaticBoxSizer *sbsizer = new wxStaticBoxSizer(sb,wxHORIZONTAL);
	de_InputDate = new wxDatePickerCtrl(this,wxID_ANY,wxDefaultDateTime,wxDefaultPosition,wxSize(120,-1),wxDP_DEFAULT|wxDP_SHOWCENTURY);
	
	de_InputType = new wxRadioBox(this,detaile_input,_("input type"),wxDefaultPosition,wxDefaultSize,2,inputtype_items,2,wxRA_SPECIFY_ROWS);
	de_IncomeType = new wxRadioBox(this,detaile_iobox,_("type of transaction"),wxDefaultPosition,wxDefaultSize,2,incometype_items,2,wxRA_SPECIFY_COLS);
	detailPanel = new wxPanel(this,wxID_ANY,wxPoint(0,0),wxSize(530,400));
	
	
	de_SettingList = new wxNotebook(detailPanel,detaile_setlist,wxDefaultPosition,wxSize(485,290),wxNB_TOP);
	de_SettingList->AddPage(setup_expensepage(de_SettingList),_("Expense and Items"),false);
	de_SettingList->AddPage(setup_calcpage(de_SettingList),_("Calculate"),false);
	//de_SettingList->AddPage(setup_memopage(de_SettingList),_("Memo"),false);

	wxStaticText *labelmemo = new wxStaticText(detailPanel,wxID_ANY,_("Memo"));
	de_MemoBox = new wxTextCtrl(detailPanel,wxID_ANY,wxEmptyString,wxPoint(-1,-1),wxSize(480,-1));
	de_MemoBox->SetMaxLength(48);

	de_OkBtn = new wxButton(this, detaile_ok, _T("OK"), wxPoint(-1,-1),wxSize(85,-1));
	de_CanBtn = new wxButton(this, detaile_can, _("Cancel"), wxPoint(-1,-1),wxSize(85,-1));
	
	//setting sizer
	sbsizer->Add(de_InputDate,0,wxTOP|wxLEFT,0);
	wxBoxSizer *bsizer1 = new wxBoxSizer(wxVERTICAL);
		wxBoxSizer *bsizer15 = new wxBoxSizer(wxHORIZONTAL);
		bsizer15->Add(sbsizer,0,wxEXPAND|wxTOP|wxLEFT,0);
		bsizer15->Add(de_InputType,0,wxLEFT,5);
		bsizer15->Add(de_IncomeType,0,wxLEFT,5);
	bsizer1->Add(bsizer15,0,wxTOP|wxLEFT,0);
	bsizer1->Add(detailPanel,0,wxTOP|wxBOTTOM,5);
		wxBoxSizer *bsizer2 = new wxBoxSizer(wxHORIZONTAL);
		bsizer2->Add(de_OkBtn,0,wxTOP|wxLEFT,0);
		bsizer2->Add(de_CanBtn,0,wxLEFT,5);
		wxBoxSizer *bsizer4 = new wxBoxSizer(wxVERTICAL);
		bsizer4->Add(de_SettingList,1,wxLEFT,5);
		bsizer4->Add(labelmemo,0,wxTOP|wxLEFT,5);
		bsizer4->Add(de_MemoBox,0,wxLEFT,5);
		bsizer4->AddSpacer(40);
		detailPanel->SetSizer(bsizer4);
		detailPanel->Layout();
	bsizer1->Add(bsizer2,0,wxRIGHT|wxALIGN_RIGHT,10);
	this->SetSizer(bsizer1);
	this->Layout();
	
	savevalue = -1;
	saveoper = -1;
	editmode = false;
	push_oper = false;
	push_enter = false;
}
wxPanel *DetailEditor::setup_expensepage(wxNotebook *book)
{
	de_ExpensePanel = new wxPanel(book,wxID_ANY);

	wxStaticText *label1 = new wxStaticText(de_ExpensePanel,wxID_ANY,_("Expense:"));
	de_ExpenseList = new wxBitmapComboBox(de_ExpensePanel,detaile_expenselist,_T(""),wxDefaultPosition,wxSize(180,32),0,NULL,wxCB_READONLY);
	wxStaticText *label2 = new wxStaticText(de_ExpensePanel,wxID_ANY,_("Items:"));
	de_ItemsList = new wxBitmapComboBox(de_ExpensePanel,wxID_ANY,_T(""),wxDefaultPosition,wxSize(180,32),0,NULL,wxCB_READONLY);
	
	wxStaticBox *sbox = new wxStaticBox(de_ExpensePanel,wxID_ANY,_("type of handling"));
	wxStaticBoxSizer *sbsizer = new wxStaticBoxSizer(sbox,wxVERTICAL);
	de_InAccounts = new wxChoice(de_ExpensePanel,wxID_ANY,wxDefaultPosition,wxSize(180,-1));
	sbsizer->Add(de_InAccounts,0,wxTOP|wxLEFT);
	de_InAccounts->Enable(true);
	
	wxBoxSizer *bsizer1 = new wxBoxSizer(wxVERTICAL);
		wxBoxSizer *bsizer2 = new wxBoxSizer(wxVERTICAL);
		bsizer2->Add(label1,0,wxTOP|wxLEFT,0);
		bsizer2->Add(de_ExpenseList,0,wxTOP|wxLEFT,5);
		bsizer2->AddStretchSpacer();
		bsizer2->Add(label2,0,wxTOP|wxLEFT,10);
		bsizer2->Add(de_ItemsList,0,wxTOP|wxLEFT,5);
		wxBoxSizer *bsizer3 = new wxBoxSizer(wxHORIZONTAL);
		bsizer3->Add(sbsizer,0,wxTOP,5);
	bsizer1->Add(bsizer3,0,wxTOP|wxLEFT,0);
	bsizer1->Add(bsizer2,0,wxTOP|wxLEFT,5);
	de_ExpensePanel->SetSizer(bsizer1);
	de_ExpensePanel->Layout();
	return de_ExpensePanel;

}
wxPanel *DetailEditor::setup_calcpage(wxNotebook *book)
{
	de_CalcPanel = new wxPanel(book,wxID_ANY);

	de_CalcLine = new wxTextCtrl(de_CalcPanel,wxID_ANY,_T("0"),wxPoint(-1,-1),wxSize(150,-1),wxTE_READONLY|wxTE_RIGHT);
	de_CalcLine->SetMaxLength(11);
	de_CalcNumBtn[0] = new wxButton(de_CalcPanel, detaile_num0, _T("0"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[1] = new wxButton(de_CalcPanel, detaile_num1, _T("1"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[2] = new wxButton(de_CalcPanel, detaile_num2, _T("2"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[3] = new wxButton(de_CalcPanel, detaile_num3, _T("3"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[4] = new wxButton(de_CalcPanel, detaile_num4, _T("4"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[5] = new wxButton(de_CalcPanel, detaile_num5, _T("5"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[6] = new wxButton(de_CalcPanel, detaile_num6, _T("6"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[7] = new wxButton(de_CalcPanel, detaile_num7, _T("7"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[8] = new wxButton(de_CalcPanel, detaile_num8, _T("8"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[9] = new wxButton(de_CalcPanel, detaile_num9, _T("9"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcNumBtn[10] = new wxButton(de_CalcPanel, detaile_num00, _T("00"), wxPoint(-1,-1),wxSize(65,-1));
	
	de_CalcFuncBtn[0] = new wxButton(de_CalcPanel, detaile_add, _T("+"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcFuncBtn[1] = new wxButton(de_CalcPanel, detaile_sub, _T("-"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcFuncBtn[2] = new wxButton(de_CalcPanel, detaile_multi, _T("*"), wxPoint(-1,-1),wxSize(30,-1));
	de_CalcFuncBtn[3] = new wxButton(de_CalcPanel, detaile_div, _T("/"), wxPoint(-1,-1),wxSize(30,-1));
	
	de_CalcEnterBtn = new wxButton(de_CalcPanel, detaile_enter, _T("="), wxPoint(-1,-1),wxSize(100,-1));
	de_CalcClearBtn = new wxButton(de_CalcPanel, detaile_clear, _T("C"), wxPoint(-1,-1),wxSize(30,-1));
	
	de_CalcClearTax = new wxButton(de_CalcPanel, detaile_cleartax, _("Exclude tax"), wxPoint(-1,-1),wxSize(85,-1));
	de_CalcIncludeTax = new wxButton(de_CalcPanel, detaile_includetax, _("Include tax"), wxPoint(-1,-1),wxSize(85,-1));
	de_CalcTax = new wxSpinCtrl(de_CalcPanel, wxID_ANY, _T("0"),wxDefaultPosition,wxSize(65,-1),wxSP_ARROW_KEYS,-100,100,0);
	wxStaticText *label1 = new wxStaticText(de_CalcPanel,wxID_ANY,_T("%"));
	de_CalcExplain = new wxStaticText(de_CalcPanel,wxID_ANY,wxEmptyString);
	de_CalcExplain->SetForegroundColour(wxColour(0,0,255));
	
	wxAcceleratorEntry acce[26];
	int kkey = 48;
	int nkey = WXK_NUMPAD0; //96;
	int evkey = detaile_num0;
	for (int i = 0; i < 10; i++) {
		acce[i].Set(wxACCEL_NORMAL, kkey, evkey);
		kkey++;
		evkey++;
	}
	evkey = detaile_num0;
	for (int i = 10; i < 20; i++) {
		acce[i].Set(wxACCEL_NORMAL, nkey, evkey);
		nkey++;
		evkey++;
	}
	acce[20].Set(wxACCEL_NORMAL, WXK_RETURN, detaile_enter);
	acce[21].Set(wxACCEL_NORMAL, WXK_NUMPAD_ADD, detaile_add);
	acce[22].Set(wxACCEL_NORMAL, WXK_NUMPAD_SUBTRACT, detaile_sub);
	acce[23].Set(wxACCEL_NORMAL, WXK_NUMPAD_MULTIPLY, detaile_multi);
	acce[24].Set(wxACCEL_NORMAL, WXK_NUMPAD_DIVIDE, detaile_div);
	acce[25].Set(wxACCEL_NORMAL, WXK_DELETE, detaile_clear);
	wxAcceleratorTable accel(26,acce);
	de_CalcPanel->SetAcceleratorTable(accel);

	wxBoxSizer *bsizer1 = new wxBoxSizer(wxVERTICAL);
	bsizer1->Add(de_CalcLine,0,wxTOP|wxLEFT,5);
		wxFlexGridSizer *fgsizer = new wxFlexGridSizer(4);
		fgsizer->Add(de_CalcNumBtn[7],0,wxLEFT,0);
		fgsizer->Add(de_CalcNumBtn[8],0,wxLEFT,5);
		fgsizer->Add(de_CalcNumBtn[9],0,wxLEFT,5);
		fgsizer->Add(de_CalcFuncBtn[3],0,wxLEFT,5);
		fgsizer->Add(de_CalcNumBtn[4],0,wxTOP,5);
		fgsizer->Add(de_CalcNumBtn[5],0,wxTOP|wxLEFT,5);
		fgsizer->Add(de_CalcNumBtn[6],0,wxTOP|wxLEFT,5);
		fgsizer->Add(de_CalcFuncBtn[2],0,wxTOP|wxLEFT,5);
		fgsizer->Add(de_CalcNumBtn[1],0,wxTOP,5);
		fgsizer->Add(de_CalcNumBtn[2],0,wxTOP|wxLEFT,5);
		fgsizer->Add(de_CalcNumBtn[3],0,wxTOP|wxLEFT,5);
		fgsizer->Add(de_CalcFuncBtn[1],0,wxTOP|wxLEFT,5);
		wxBoxSizer *bsizer2 = new wxBoxSizer(wxHORIZONTAL);
		bsizer2->Add(de_CalcNumBtn[0],0,wxTOP,5);
		bsizer2->Add(de_CalcNumBtn[10],0,wxTOP|wxLEFT,5);
		bsizer2->Add(de_CalcFuncBtn[0],0,wxTOP|wxLEFT,5);
		wxBoxSizer *bsizer3 = new wxBoxSizer(wxHORIZONTAL);
		bsizer3->Add(de_CalcEnterBtn,0,wxTOP,5);
		bsizer3->Add(de_CalcClearBtn,0,wxTOP|wxLEFT,5);
	
	bsizer1->Add(fgsizer,0,wxTOP|wxLEFT,5);
	bsizer1->Add(bsizer2,0,wxLEFT,5);
	bsizer1->Add(bsizer3,0,wxTOP|wxLEFT,5);
	wxBoxSizer *bsizer4 = new wxBoxSizer(wxVERTICAL);
	bsizer4->Add(de_CalcClearTax,0,wxTOP|wxLEFT,5);
	bsizer4->Add(de_CalcIncludeTax,0,wxTOP|wxLEFT,5);
		wxBoxSizer *bsizer6 = new wxBoxSizer(wxHORIZONTAL);
		bsizer6->Add(de_CalcTax,0,wxTOP|wxLEFT,0);
		bsizer6->Add(label1,0,wxTOP|wxLEFT,3);
	bsizer4->Add(bsizer6,0,wxTOP|wxLEFT,5);
	wxBoxSizer *bsizer5 = new wxBoxSizer(wxHORIZONTAL);
	bsizer5->Add(bsizer1,0,wxTOP|wxLEFT,0);
	bsizer5->Add(bsizer4,0,wxTOP|wxLEFT,0);
	wxBoxSizer *bsizer7 = new wxBoxSizer(wxVERTICAL);
	bsizer7->Add(bsizer5,0,wxTOP|wxLEFT,0);
	bsizer7->Add(de_CalcExplain,0,wxTOP|wxLEFT,0);
	de_CalcPanel->SetSizer(bsizer7);
	de_CalcPanel->Layout();
	return de_CalcPanel;

}
void DetailEditor::de_OkBtn_clicked(wxCommandEvent &event)
{
	//case of Balance alignment
	if (de_InputType->GetSelection() == 1) {
		wxString sql = StrF(_T("select tot_remainder from db_total where tot_handle = %d order by tot_date desc limit 1;"),
			GetDataHandling());
		int nowremainder = wxGetApp().SQLDB().ExecuteScalar(sql);
		int difvalue = 0;
		if (GetDataValue() >= nowremainder) {
			difvalue = GetDataValue() - nowremainder;
			de_IncomeType->SetSelection(0);
		}else{
			difvalue = nowremainder - GetDataValue();
			de_IncomeType->SetSelection(1);
		}
		de_CalcLine->SetValue(IntToStr(difvalue));
		//executed normally operation
		de_InputDate->SetValue(wxDateTime::Now());
		de_IncomeType_selected((wxCommandEvent &)event);
		//choose default expense and items
		de_ExpenseList->SetSelection(0);
		de_ExpenseList_selected((wxCommandEvent &)event);
		de_ItemsList->SetSelection(0);
	}
	if ((de_ItemsList->GetCount() == 0) || (de_ItemsList->GetSelection() < 0)) {
		int ret = wxMessageBox(_("Item of the expense is not chosen.\nDo you really continue it?\n(You can change it later.)"),APPTITLE,wxYES_NO|wxICON_QUESTION,this);
		if (ret == wxNO) {
			return;
		}
	}
	if (de_ExpenseList->GetSelection() == 1) {
		if (de_InAccounts->GetSelection() == de_ItemsList->GetSelection()) {
			wxMessageBox(_("Target account is same with type of handling"),APPTITLE,wxOK|wxICON_EXCLAMATION,this);
			return;
		}
	}
	if (editmode) {
		if (de_ExpenseList->GetSelection() != oldexpense) {
			if (de_ExpenseList->GetSelection() == 1) {
				wxMessageBox(_("You can not change expense of existed data to [from/to other account]."),APPTITLE,wxOK|wxICON_EXCLAMATION,this);
				return;
			}
		}
	}
	ChangeEnable(detaile_input,true);
	ChangeEnable(detaile_handle,true);
	ChangeEnable(0,true);
	de_SettingList->SetSelection(0);
	this->EndModal(detaile_ok);
	this->Hide();
}
void DetailEditor::de_CanBtn_clicked(wxCommandEvent &event)
{
	ChangeEnable(detaile_input,true);
	ChangeEnable(detaile_handle,true);
	ChangeEnable(0,true);
	de_SettingList->SetSelection(0);
	this->EndModal(detaile_can);
	this->Hide();
}
//=====================================================================================
//
// Event to push Number button 
//
//=====================================================================================
void DetailEditor::de_CalcNumBtn_clicked(wxCommandEvent &event)
{
	wxString line;
	//error conditions
	if (de_CalcLine->GetValue().Len() == 9) {
		return;
	}
	if (de_CalcLine->GetValue().Find(_T("E")) != wxNOT_FOUND) {
		return;
	}
	wxButton *button = (wxButton*)event.GetEventObject();
	//---you pushed 0 or 00 button
	if ((event.GetId() == detaile_num0) && (event.GetId() == detaile_num00)) {
		//---de_CalcLine is not empty and left side of the value is zero
		if (!de_CalcLine->GetValue().IsEmpty()) {
			if (de_CalcLine->GetValue().Left(1) == _T("0")) {
				return;
			}
		}
	}else{
		if (de_CalcLine->GetValue().Len() == 1) {
			if (de_CalcLine->GetValue().Left(1) == _T("0")) {
				de_CalcLine->Clear();
			}
		}
	}
	//---actual inputation
	if (push_oper) {
		de_CalcLine->Clear();
		push_oper = false;
	}
	if (push_enter) {
		de_CalcLine->Clear();
		push_enter = false;
	}
	line.Append(de_CalcLine->GetValue());
	//line.Append(button->GetLabel());
	switch (event.GetId()) {
	case detaile_num00:
		line.Append(_T("00"));
		break;
	default:
		line.Append(wxString::Format(_T("%d"),event.GetId()-52));
	}
	de_CalcLine->SetValue(line);
	//push_oper = false;
	de_CalcEnterBtn->SetFocus();
}
//=====================================================================================
//
// Event to push Operator button 
//
//=====================================================================================
void DetailEditor::de_CalcFuncBtn_clicked(wxCommandEvent &event)
{
	wxButton *button = (wxButton*)event.GetEventObject();
	long tmp;

	if (push_oper) {
		return;
	}
	if (de_CalcLine->GetValue().Find(_T("E")) != wxNOT_FOUND) {
		return;
	}
	//---Add to stack the numbers already entered
	if (!de_CalcLine->GetValue().ToLong(&tmp)) return;
	expr.push((int)tmp);
	if (expr.size() == 2) {
		//---If there are two numbers, to begin computation.
		if (expr_oper.size() < 1) {
			expr_oper.push(event.GetId());
		}
		de_CalcEnterBtn_clicked(event);
		de_CalcLine->GetValue().ToLong(&tmp);
		expr.push((int)tmp);
	}
	//---add to stack for the operator operator of de_CalcFuncBtn
	expr_oper.push(event.GetId());
	push_oper = true;
	push_enter = false;
	savevalue = -1;
	//de_CalcTax->SetValue(0);
	de_CalcEnterBtn->SetFocus();
}
//=====================================================================================
//
// Event to push Enter(Calculate) button 
//
//=====================================================================================
void DetailEditor::de_CalcEnterBtn_clicked(wxCommandEvent &event)
{
	unsigned int expr1, expr2;
	int oper, result;
	long tmp;
	if (de_CalcLine->GetValue().Find(_T("E")) != wxNOT_FOUND) {
		return;
	}
	//---if number of expression is one
	if (expr.size() == 1) {
		if (!de_CalcLine->GetValue().ToLong(&tmp)) return;
		expr.push((int)tmp);
	}
	//---calculate, if number of expression is two, more...
	if (expr.size() == 2) {
		expr2 = expr.top(); expr.pop();
		expr1 = expr.top(); expr.pop();
		oper = expr_oper.top(); expr_oper.pop();
		//judge range of expression
		//wxMessageBox(wxString::Format(_T("%d\n%d\n%u\n%d"),expr1,expr2,expr1*expr2,INT_MAX),_T("abc"),wxOK,this);
		bool test1 = ((oper == detaile_multi) && ((expr1 * expr2) >= 1000000000));
		bool test2 = ((oper == detaile_add) && ((expr1 + expr2) >= 1000000000));
		if (test1 || test2) {
			de_CalcLine->SetValue(_T("E"));
		}else{
			//---Actual computation
			result = calc_expressionStack(expr1, expr2, oper);
			if (result == -1) {
				de_CalcLine->SetValue(_T("E"));
				wxMessageBox(_("Zero divide error!"),APPTITLE,wxOK|wxICON_ERROR,this);
			}else{
				de_CalcLine->SetValue(wxString::Format(_T("%d"),result));
				//---save current result of calculation
				//expr.push(result);
				//saveoper = oper;
			}
		}
	}
	push_oper = false;
	push_enter = true;
	savevalue = -1;
	//de_CalcTax->SetValue(100);
	de_CalcEnterBtn->SetFocus();
}
void DetailEditor::de_CalcClearBtn_clicked(wxCommandEvent &event)
{
	de_CalcLine->Clear();
	de_CalcLine->SetValue(_T("0"));
	while (!expr.empty()) {
		expr.pop();
	}
	while (!expr_oper.empty()) {
		expr_oper.pop();
	}
	push_oper = false;
	push_enter = false;
	savevalue = -1;
	//de_CalcTax->SetValue(100);
}
int DetailEditor::calc_expressionStack(unsigned int e1, unsigned int e2, int op)
{
	switch (op) {
	case detaile_add:
		return e1 + e2;
	case detaile_sub:
		return e1 - e2;
	case detaile_multi:
		return e1 * e2;
	case detaile_div:
		if (e2 == 0) {
			return -1;
		}
		return e1 / e2;
	}
	return 0;
}
void DetailEditor::de_CalcClearTax_clicked(wxCommandEvent &event)
{
	//de_CalcTax->SetValue(100);
	if (de_CalcLine->IsEmpty()) {
		return;
	}
	addTax(0);
}
void DetailEditor::de_CalcIncludeTax_clicked(wxCommandEvent &event)
{
	if (de_CalcLine->IsEmpty()) {
		return;
	}
	addTax(de_CalcTax->GetValue());
}
void DetailEditor::addTax(int pos)
{
	long tmp = -1;
	int findpos;
	float ret = (float)pos / 100.0;
	float result, finaltax;
	wxString resultStr;
	if (savevalue == -1) {
		de_CalcLine->GetValue().ToLong(&tmp);
		savevalue = tmp;
	}
	finaltax = (float)savevalue * ret;
	result = (float)savevalue + finaltax;
	resultStr = wxString::Format(_T("%f"),result);
	findpos = resultStr.Find(_T("."));
	de_CalcLine->SetValue(resultStr.Mid(0,findpos));

}
void DetailEditor::bindData_InputDate(wxDateTime dt)
{
	if (dt.IsValid()) {
		de_InputDate->SetValue(dt);
	}
}
void DetailEditor::de_IncomeType_selected(wxCommandEvent &event)
{
	InoutType io = (InoutType)de_IncomeType->GetSelection();
	SetExpense(io);
	de_ExpenseList->SetSelection(0);
	if (dbexpenseId.size() > 0) {
		SetItems(dbexpenseId.at(0));
	}
	if (de_ItemsList->GetCount() > 0) {
		de_ItemsList->SetSelection(0);
	}
}
void DetailEditor::de_ExpenseList_selected(wxCommandEvent &event)
{
	int sel = de_ExpenseList->GetSelection();
	SetItems(dbexpenseId.at(sel));
	if (de_ItemsList->GetCount() > 0) {
		de_ItemsList->SetSelection(0);
	}
}
void DetailEditor::de_InputType_changed(wxCommandEvent &event)
{
	if (event.GetSelection() == 1) {
		ChangeEnable(event.GetId(),false);
	}else{
		ChangeEnable(event.GetId(),true);
	}
}
void DetailEditor::de_SettingList_changed(wxNotebookEvent &event)
{
	if (event.GetSelection() == 1) {
		de_CalcClearBtn->SetFocus();
	}
}
void DetailEditor::SetExpense(InoutType io)
{
	wxString sql = _T("select ex_id, ex_image, ex_name from db_expense where ex_io = %d");
	wxSQLite3ResultSet rset = wxGetApp().SQLDB().ExecuteQuery(
		wxString::Format(sql,(int)io));
	de_ExpenseList->Clear();
	dbexpenseId.clear();
	while (rset.NextRow()) {
		dbexpenseId.push_back(rset.GetInt(0));
		int i = rset.GetInt(1);
		if (i > -1) {
			de_ExpenseList->Append(rset.GetString(2),wxGetApp().icoDList->GetBitmap(i));
		}else{
			de_ExpenseList->Append(rset.GetString(2));
		}
	}
}
void DetailEditor::SetItems(int expenseId)
{
	wxString sql = _T("select it_id, it_image, it_name from db_items where it_expense = %d");
	wxSQLite3ResultSet rset = wxGetApp().SQLDB().ExecuteQuery(
		wxString::Format(sql,expenseId));
	de_ItemsList->Clear();
	dbitemsId.clear();
	while (rset.NextRow()) {
		dbitemsId.push_back(rset.GetInt(0));
		int i = rset.GetInt(1);
		if (i > -1) {
			de_ItemsList->Append(rset.GetString(2),wxGetApp().icoDList->GetBitmap(i));
		}else{
			de_ItemsList->Append(rset.GetString(2));
		}
	}
}
void DetailEditor::SetAccount(int handle)
{
	wxString sql = _T("select * from db_account");
	wxSQLite3ResultSet rset = wxGetApp().SQLDB().ExecuteQuery(sql);
	de_InAccounts->Clear();
	dbaccountId.clear();
	while (rset.NextRow()) {
		dbaccountId.push_back(rset.GetInt(0));
		de_InAccounts->Append(rset.GetString(1));
	}
	//choose default handle
	if (handle == -1) {
		de_InAccounts->SetSelection(0);
	}else{
		int i;
		for (i = 0; i < (int)dbaccountId.size(); i++) {
			if (handle == dbaccountId.at(i)) {
				de_InAccounts->SetSelection(i);
				break;
			}
		}
	}
}
void DetailEditor::bindData_ExistData(DB_day db)
{
	de_IncomeType->SetSelection((int)db.GetIO());
	SetExpense(db.GetIO());
	SetItems(db.GetExpense());
	for (int i = 0; i < (int)dbexpenseId.size(); i++) {
		if (db.GetExpense() == dbexpenseId.at(i)) {
			de_ExpenseList->SetSelection(i);
			oldexpense = i;
			break;
		}
	}
	for (int i = 0; i < (int)dbitemsId.size(); i++) {
		if (db.GetItems() == dbitemsId.at(i)) {
			de_ItemsList->SetSelection(i);
			olditems = i;
			break;
		}
	}
	int i;
	for (i = 0; i < (int)dbaccountId.size(); i++) {
		if (db.GetHandling() == dbaccountId.at(i)) {
			de_InAccounts->SetSelection(i);
			break;
		}
	}
	if (db.GetIO() == in_it) {
		de_CalcLine->SetValue(IntToStr(db.GetIncome()));
	}else{
		de_CalcLine->SetValue(IntToStr(db.GetExpenditure()));
	}
	de_MemoBox->SetValue(db.GetMemo());
	
	ChangeEnable(0,false);
	editmode = true;
}
void DetailEditor::ChangeEnable(int type, bool flag)
{
	if (type == detaile_input) {
		if (!flag) de_SettingList->SetSelection(1);
		de_SettingList->GetPage(0)->Enable(flag);
		de_IncomeType->Enable(flag);
		if (flag) {
			de_CalcExplain->SetLabel(wxEmptyString);
		}else{
			de_CalcExplain->SetLabel(_("Please input new remainder"));
		}
	}else if (type == detaile_handle) {
		de_InAccounts->Enable(flag);
	}else if (type == -1) {//call from external
		de_InputType->Enable(flag);
	}else if (type == -2) {//call as periodical transaction
		de_InputType->Enable(flag);
		de_IncomeType->Enable(flag);
	}else{
		//de_InputDate->Enable(flag);
		de_InAccounts->Enable(flag);
		de_InputType->Enable(flag);
		de_IncomeType->Enable(flag);
	}
}
void DetailEditor::ClearControl(void) {
	de_InputType->SetSelection(0);
	de_IncomeType->SetSelection(0);
	de_CalcLine->Clear();
	de_MemoBox->Clear();
	editmode = false;
}
